package com.lkbaby.flowable;

import com.lkbaby.cmd.MyAddCommentCmd;
import com.lkbaby.pojo.Comment;
import com.lkbaby.pojo.CommentMapper;
import org.flowable.engine.ManagementService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.persistence.entity.CommentEntity;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping("/test")
@Transactional
public class MyProcess {

	@Autowired
	private RepositoryService repositoryService;

	@Autowired
	private RuntimeService runtimeService;

	@Autowired
	private TaskService taskService;

	@Autowired
	private ManagementService managementService;

	@Autowired
	private CommentMapper commentMapper;

	/**
	 * 流程部署
	 *
	 * @throws Exception
	 */
	@RequestMapping("/deploy")
	public void testDeploy() {

		List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
				.processDefinitionKey("flowableAppoint").list();
		for (ProcessDefinition definition : processDefinitions) {
			System.out.println(definition.getDeploymentId());
			repositoryService.deleteDeployment(definition.getDeploymentId(), true);
		}

		Deployment deploy = repositoryService.createDeployment()
				.addClasspathResource("processes/委派.bpmn20.xml")
				.name("委派")
				.deploy();
		System.out.println("deploy.getId() = " + deploy.getId());
		System.out.println("deploy.getName() = " + deploy.getName());
		System.out.println("部署开始的时间：" + new Date());
		//TimeUnit.MINUTES.sleep(3);
	}

	/**
	 * 启动流程
	 *
	 * @throws Exception
	 */
	@RequestMapping("/startFlow")
	public void startFlow() {
		// 获取process
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
				.processDefinitionKey("flowableAppoint").singleResult();
		Map<String, Object> map = new HashMap<>();
		// 设置多人会签的数据
		map.put("persons", Arrays.asList("张三", "李四"));
		map.put("status", false);
		//拒绝人数
		map.put("reject", 0);
		//同意人数
		map.put("agree", 0);
		ProcessInstance processInstance = runtimeService
				.startProcessInstanceById(processDefinition.getId(), map);
	}

	/**
	 * 完成一个任务
	 */
	@RequestMapping("/completeOne")
	public void completeTask1(@RequestParam String userKey) {

		Task task = taskService.createTaskQuery()
				.processDefinitionKey("flowableAppoint")
				.taskAssignee(userKey)
				.singleResult();

		if (task == null) {
			return;
		}

		String taskId = task.getId();

		Map<String, Object> map = new HashMap<>();
		// 同意 agree + 1
		Integer agree = (int) taskService.getVariable(task.getId(), "agree");
		map.put("agree", agree + 1);
		taskService.complete(task.getId(), map);

		// 添加备注
		String message = "来自" + userKey + "的测试评论";
		// AddCommentCmd(String taskId, String processInstanceId, String type, String message)
		managementService.executeCommand(
				new MyAddCommentCmd(taskId, userKey, task.getProcessInstanceId(), CommentEntity.TYPE_COMMENT, message));
		// 备注列表
		System.out.println("==============>");
		commentMapper.getFlowCommentVosByProcessInstanceId(task.getProcessInstanceId()).forEach(System.out::println);

	}

	/**
	 * 获取评论列表
	 */
	@ResponseBody
	@RequestMapping("/getComment/{id}")
	public List<Comment> getComments(@PathVariable("id") String processInstanceId) {
		System.out.println(processInstanceId);
		List<Comment> comments = commentMapper
				.getFlowCommentVosByProcessInstanceId(processInstanceId);
		System.out.println(comments.size());
		System.out.println(comments);
		return comments;
	}

	/**
	 * 委派
	 */
	@RequestMapping("/appoint")
	public void addSign(@RequestParam String userKey) {

		Task task = taskService.createTaskQuery()
				.processDefinitionKey("flowableAppoint")
				.taskAssignee(userKey)
				.singleResult();
		System.out.println("Task key：" + task.getTaskDefinitionKey()
				+ "\nTask Name：" + task.getName()
				+ "\n流程实例ID：" + task.getProcessInstanceId());
		taskService.delegateTask(task.getId(), "王五");
		System.out.println("委派成功");
	}

	/**
	 * 处理委派任务
	 */
	@RequestMapping("/resolveAppoint")
	public void appoint(@RequestParam String userKey) {
		Task task = taskService.createTaskQuery()
				.processDefinitionKey("flowableAppoint")
				.taskAssignee(userKey)
				.singleResult();
		taskService.resolveTask(task.getId());
	}
}
